package cn.wolfcode.wolf2w.service.impl;

import cn.wolfcode.wolf2w.domain.Destination;
import cn.wolfcode.wolf2w.domain.Region;
import cn.wolfcode.wolf2w.domain.Strategy;
import cn.wolfcode.wolf2w.domain.StrategyCatalog;
import cn.wolfcode.wolf2w.query.DestinationQuery;
import cn.wolfcode.wolf2w.query.QueryObject;
import cn.wolfcode.wolf2w.repository.DestinationRepository;
import cn.wolfcode.wolf2w.service.IDestinationService;
import cn.wolfcode.wolf2w.service.IRegionService;
import cn.wolfcode.wolf2w.service.IStrategyCatalogService;
import cn.wolfcode.wolf2w.service.IStrategyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

@Service
public class DestinationServiceImpl implements IDestinationService {
    @Autowired
    private DestinationRepository destinationRepository;
    @Autowired
    private IRegionService regionService;
    @Autowired
    private MongoTemplate template;
    @Autowired
    private IStrategyCatalogService strategyCatalogService;
    @Autowired
    private IStrategyService strategyService;

    @Override
    public void insert(Destination destination) {
        destinationRepository.save(destination);
    }

    @Override
    public void delete(String id) {
        destinationRepository.deleteById(id);
    }

    @Override
    public void update(Destination destination) {
        destinationRepository.save(destination);
    }

    @Override
    public Destination selectOne(String id) {
        Optional<Destination> destination = destinationRepository.findById(id);
        return destination.orElse(null);
    }

    @Override
    public List<Destination> list() {
        List<Destination> all = destinationRepository.findAll();
        return all;
    }

    @Override
    public List getDestByRegionId(String rid) {
        Region region = regionService.selectOne(rid);
        List list = destinationRepository.findByIdIn(region.getRefIds());
        return list;
    }

    @Override
    public Page<Destination> query(QueryObject qo, String parentId) {

        Query query = new Query();

        if (StringUtils.hasText(qo.getKeyword()) && !StringUtils.hasText(parentId) ){
            query.addCriteria(Criteria.where("name").regex(qo.getKeyword()));
        }else if (StringUtils.hasText(qo.getKeyword()) && StringUtils.hasText(parentId) ){

            query.addCriteria(Criteria.where("name").regex(qo.getKeyword()));
            query.addCriteria(Criteria.where("parentId").is(parentId));

        } else {

            if (StringUtils.hasText(parentId)){
                query.addCriteria(Criteria.where("parentId").is(parentId));
            }else {
                query.addCriteria(Criteria.where("parentId").is(null));
            }

        }
        long total = template.count(query, Destination.class);
        if (total == 0){
            return Page.empty();
        }
        Pageable pageable = PageRequest.of(qo.getCurrentPage() - 1, qo.getPageSize(),Sort.Direction.ASC, "_id");
        query.with(pageable);
        List<Destination> list = template.find(query, Destination.class);
        return new PageImpl<>(list, pageable,total);


    }

    @Override
    public List queryToasts(String parentId) {
        ArrayList<Destination> toasts = new ArrayList<>();
        while (parentId != null){
            Optional<Destination> destination = destinationRepository.findById(parentId);
            Destination destination1 = destination.orElse(null);
            if (destination1 != null){
                toasts.add(destination1);
                parentId = destination1.getParentId();
            }else {
                parentId = null;
            }
        }
        Collections.reverse(toasts);
        return toasts;
    }

    @Override
    public void updateInfoById(String id, String info) {
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(id));
        Update update = new Update();
        update.set("info", info);
        template.updateMulti(query,update ,Destination.class );
    }

    @Override
    public List queryDestinationByRegionId(String regionId) {
        List<Destination> destinations = new ArrayList();
        if ("-1".equals(regionId)){
            destinations = destinationRepository.findByParentName("中国");
        }else {
            Region region = regionService.selectOne(regionId);
            destinations = destinationRepository.findByIdIn(region.getRefIds());
        }

        for (Destination destination : destinations) {
            destination.setChildren(destinationRepository.findByParentId(destination.getId()));
        }
        return destinations;
    }

    @Override
    public List findByDeep(int deep) {
        List destination = destinationRepository.findByDeep(deep);
        return destination;
    }

    @Override
    public List queryStrategyTheme(String destId) {
        //先查攻略分类
        List<StrategyCatalog> strategyCatalogs = strategyCatalogService.findByDestId(destId);
        //查询每个攻略下的对应的所有的攻略
        for (StrategyCatalog strategyCatalog : strategyCatalogs) {
            List<Strategy> strategies = strategyService.findByCatalogId(strategyCatalog.getId());
            strategyCatalog.setStrategies(strategies);
        }
        return strategyCatalogs;
    }

    @Override
    public Destination findByName(String keyword) {
        Destination destination = destinationRepository.findByName(keyword);
        return destination;
    }


}
